<?php
class User 
{
	protected static $_user    = NULL;
	protected static $_user_id = NULL;
	protected static $_search  = NULL;
	protected static $_current_passport = NULL;
    protected static $_currentUser = NULL;

    public static function currentUser ()
    {
        $request = Request::initial();
        $directory = $request->directory();
        if ($directory == 'admin')
            return new User_V2_Guest();

        if (self::$_currentUser === NULL)
        {
            $uid = Passport::getCurrentUserUid();
	        if ($uid > 0)
	            self::$_currentUser = self::getUserFromUid($uid);
	        else
	            self::$_currentUser = new User_v2_Guest();
        }

        return self::$_currentUser;
    }

    public static function initUserFromBasicInfo ($source, $userId, $userToken, 
            $userName, $userIcon, $userGender, $userPushId,$utype="")
    {
        $query = DB::select()
            ->from('user_v2')
            ->where('source', '=', $source)
            ->where('userid', '=', $userId)
            ->execute();

        if ($query->count() > 0)
        {
            $current = $query->current();
            $uid     = $current['uid'];
            $status  = $current['status'];
            if ($status != 1)
                return new User_v2_Guest();
            else
            {
                $curr = $query->current();
                $uid  = $curr['uid'];
                Passport::setCurrentUserUid($uid);
                return $uid;
//                $user = new User_v2_Member($uid, $current);
//                $user->updateUserPushId($userPushId);
//                return $user;
            }
        }
        else
        {
            $uid = self::createUser ($source, $userId, $userToken, $userName, $userIcon, $userGender,$utype);
            if ($uid > 0)
            {
                $data['userIcon'] = $userIcon;
                $data['uid'] = $uid;
                User_UserInfo::create($data);
                Passport::setCurrentUserUid($uid);
                return $uid;
//                $user = self::getUserFromUid($uid);
              //  $user->updateUserPushId($userPushId);
//                return $user;
            }
//            else
//                return new User_v2_Guest();
        }
    }

    public static function createUser ($source, $userId, $userToken, $userName, $userIcon, $userGender,$utype="")
    {
        $time = time();
        $row = array(
            'source' => $source,
            'userId' => $userId,
            'userName' => $userName,
            'userToken' => $userToken,
            'userIcon'  => $userIcon,
            'userGender' => $userGender,
            'status'     => 1,
            'created'    => $time,
            'changed'    => $time,
            'utype'    => $utype,
        );

        try {
	        list($insertId, $rows) = DB::insert('user_v2')
	            ->columns (array_keys($row))
	            ->values (array_values($row))
	            ->execute();
	
	        return $insertId;
        }
        catch (Exception $e)
        {
            return 0;
        }
    }

    public static function getUserFromUid ($uid)
    {
        $query = DB::select()
            ->from('user_v2')
            ->where('uid', '=', (int) $uid)
            ->execute();

        if ($query->count() > 0)
        {
            $current = $query->current();
            $uid     = $current['uid'];
            $status  = $current['status'];
            if ($status != 1)
                return new User_v2_Guest();
            else
                return new User_v2_Member($uid, $current);
        }
        else
        {
            return new User_v2_Guest();
        }
    }

	/*
	 * 当前登录用户的UID
	 *
	 * @return	int	 $uid
	 */
	public static function current_user_id()
	{
		if (NULL === self::$_user_id)
		{
			$info = self::current_user_info ();
			if (!empty($info) AND isset($info['uid']))
				self::$_user_id = intval($info['uid']);
			else
				self::$_user_id = 0;
		}

		return self::$_user_id;
	}

	/*
	 * 当前登录用户的昵称(若是游客，则显示为'游客')
	 *
	 * @param	string  $name_type : ['nickname', 'realname']
	 * @return	string	$nickname
	 */
	public static function current_user_name ($name_type = 'nickname')
	{
		$info = self::current_user_info();
		return Arr::get($info, $name_type, NULL);
	}

	/*
	 * 根据UID返回用户的名字
	 *
	 * @param	int		$uid 
	 * @param	string	$name_type : ['nickname', 'realname']
	 * @return	string  
	 */
	public static function name ($uid = NULL, $name_type = 'nickname')
	{
		if (NULL === $uid)
			return self::current_user_name($name_type);
		else
		{
			$user = self::instance($uid);
			if (is_object ($user))
				return $user->get_user_name($name_type);
			else
				return '';
		}
	}

	/**
	 * 返回用户的IM: (注：当前仅返回member用户的im信息)
	 *
	 * @param	int		$uid [optional]
	 * @return	array(
	 *		'number' => string,
	 *		'type'   => int,
	 *		'nickname' => string,
	 *	);
	 * @return	NULL if failure
	 */
	public static function im ($uid = NULL)
	{
		$uid  = empty($uid) ? self::current_user_id() : (int) $uid;
		$user = self::instance($uid);
		if (! empty($user) AND $user->get_role_id() == 'member')
		{
			return $user->get_im();
		}
		else
			return '';
	}

	public static function passport () 
	{
		if (NULL === self::$_current_passport)
		{
            $passport = Passport::current_user_sid();
			if (empty($passport))
				self::$_current_passport = '';
			else
				self::$_current_passport = $passport;
		}

		return self::$_current_passport;
	}

    public static function currentAdminUser()
    {
        return self::current_user();
    }

	/*
	 * 当前登录的用户对象实例 (若是游客，则返回Guest)
	 *
	 * @return	object $user_instance
	 */
	public static function current_user ()
	{
		if (NULL === self::$_user)
		{
            $passport = Passport::current_user_sid();
			if (empty($passport))
            {
				self::$_user = new User_Guest();
            }
			else
			{
				self::$_user = self::factory ($passport);
				if (self::$_user === NULL)
					self::$_user = new User_Guest();
			}
		}

		return self::$_user;
	}

	/*
	 * 当前登录用户的基本信息 
	 *
	 * @return array	$user_info_list :
	 *		array(
	 *			'uid'      => 10032, 
	 *		    'username' => 'lucy', 
	 *		    'passport' => '123@sohu.com',
	 *			'mobile'   => '13401067714',
	 *		);
	 * @return NULL if not login
	 */
	public static function current_user_info ()
	{
		return self::current_user()->get_user_info();
	}

	/*
	 * 当前用户是否处于登录状态
	 *
	 * @return boolean	
	 */
	public static function is_login ()
	{
		return self::current_user()->is_login();
	}


	/**
	 * 当前用户是否有消息通知
	 */
	public static function has_notice ()
	{
		return self::current_user()->has_notice();
	}
	
	/**
	 * 增加当前用户的消息通知
	 */
	public static function add_notice ($uid = NULL)
	{
		if (empty($uid))
			return self::current_user()->increase_notice();
		else if ($uid > 0)
			return self::instance($uid)->increase_notice();
	}

	/**
	 * 清除当前用户的消息通知
	 */
	public static function clean_notice ()
	{
		return self::current_user()->clean_notice();
	}

	/*
	 * 当前是否有商家在登录
	 */
	public static function current_merchant_uid ()
	{
		if (site::type() == 'merchant')
			return self::current_user_id();
        else
            return 0;
	}

	/*
	 * 当前用户是否已经激活
	 *
	 * @return boolean
	 */
	public static function is_activated ()
	{
		return self::current_user()->is_activated();
	}

	/*
	 * 当前用户手机是否绑定
	 *
	 * @return boolean
	 */
	public static function mobile_binded ()
	{
		return self::current_user()->mobile_binded();
	}


	/*
	 * 工厂式方法生产出一个用户实例, 包括(游客，普通用户，商家，管理员)
	 *
	 * @param	int	 $uid
	 * @param	string	$utype : ['manager', 'merchant', 'member']
	 *
	 * @return	Object User
	 * @return	NULL if invalid
	 */
	public static function instance ($uid) 
	{
		if ($uid <= 0)
			return NULL;

		$info = User_Base::user_info_by_uid ($uid);
		if (empty($info))
		{
			$user = new User_Guest();
			$info = $user->get_user_info();
		}

		return self::do_user_instance ($info);
	}

	/*
	 * 当前用户是否已登录Passport系统
	 *
	 * @return boolean	
	 */
	public static function is_passport_login ()
	{
		return self::current_user()->is_passport_login();
	}


	/*
	 * 工厂式方法生产出一个用户实例, 包括(游客，普通用户，商家，管理员)
	 *
	 * @param	string	 $passport
	 * @param	string	 $utype : ['manager', 'merchant', 'member']
	 *
	 * @return	Object User
	 */

	public static function factory ($passport, $type = NULL)
	{
		if (empty($type))
			$type = site::type();

		if (empty($passport))
			return NULL;

		$info = User_Base::user_info_by_passport ($passport, $type);
        if (empty($info))
        {
            //
            // 在网盟前台，若用户没有渠道商的身份，就使用会用的身份
            // 
            if ($type == 'merchant') 
            {
		        $info = User_Base::user_info_by_passport ($passport, 'member');
            }

            if (empty($info))
			    return NULL;
        }

		return self::do_user_instance($info);
	}

	/*
	 * 是否存在该passport对应的站点账户
	 *
	 * @param	string $passport
	 * @param	string $utype 
	 * @return	boolean
	 */
	public static function has_user ($passport, $utype = NULL)
	{
		if (empty($type))
			$type = site::type();

		if (empty($passport))
			return FALSE;

		return User_Base::has_user ($passport, $type);
	}

	/*
	 * 创建新用户账户
	 *
	 * @param	array $info = array(
	 *		'passport' => string,
	 *		'mobile'   => string,
	 *		'nickname' => string,
     *		'password'   => string,
	 *		);
	 *
	 * @param	string	$user_type ['manager', 'merchant']
	 * @param	int		$user_status : see Kohana::config('user.status.xxx')
	 * @return  int		$uid
	 */
	public static function create ($info, $status = 'unactivated', $utype = 'merchant')
	{
        $passport = Arr::get($info, 'passport');
        $password = Arr::get($info, 'password');

        $pst = new Passport;
        if ($pst->create ($passport, $password))
        {
            unset($info['password']);

		    $info['create_time'] = time();
		    $info['create_ip'  ] = Request::$client_ip;
		    $info['status'     ] = Kohana::config("user.status.$status");
		    $info['utype'      ] = $utype;
            $info['lastlogin_time'] = 0;
            $info['lastlogin_ip']   = '';

            try {
		        $uid = User_Base::create($info);

		        if ($uid > 0)
		        {
			        $info['uid'] = (int) $uid;
			        Events::notify(Kohana::config('events.user.created'), $info);
		        }
            }
            catch (Exception $e)
            {
                echo $e->getMessage();exit;
                throw new Exception("用户已存在");
            }

		    return $uid;
        }
        else
        {
            return 0;
        }

	}

	/*
	 * 用户搜索
	 *
	 * @param	array $search
	 *      'uid'      => int or array(int, int,.....) UID
	 *		'nickname' => string, 用户昵称
	 *		'realname' => string, 用户姓名
	 *		'passport' => string, passport
	 *		'site'     => string, 只能是'member', 'merchant', 'manager'
	 *		'status'   => string or array(string1, string2,...) 
	 *			用户状态: 如: 'activated' or array('activated', 'mobile_binded')
	 *
	 *		'create_time_greater', 'create_time_less' => int,
	 *		'lastlogin_time_greater', 'lastlogin_time_less' => int,
	 *		'logins_greater', 'logins_less' => int,
	 *
	 *      排序: 
	 *			'order_by' => array(
	 *					string $by1	=> string $order1, 
	 *					string $by2	=> string $order2, 
	 *					...
	 *					);
	 *			其中:
	 *				$by    = ['uid', 'create_time', 'lastlogin_time'] 
	 *				$order = 'ASC' | 'DESC';
	 *
	 */
	public static function search($query, $start = NULL, $limit = NULL)
	{
		return self::search_engine()->search($query, $start, $limit);
	}

	/**
	 * 用户统计
	 * 
	 * @param	string	$type:  应使用一下类型之一
	 *
	 *			'status',			// 用户状态
	 *
	 * @param	int		start_time  用户创建时间(开始)
	 * @param	int		end_time	用户创建时间(结束)
	 *
	 * @return	array
	 */
	public static function statistics ($type, $start_time = NULL, $end_time = NULL)
	{
		$role   = User::current_user()->get_role_id();
		$search = array();
	
		switch ($type)
		{
			case 'status' :
				$search = array(
					'select'   => array(
						array('count("u.uid")', 'count'), 
						'status',
					),
					'group_by'            => 'status',
					'enable_search_count' => FALSE,
					'format_results'      => FALSE,
				);
			break;
		}

		if (NULL !== $start_time)
			$search['create_time_greater'] = (int) $start_time;
		if (NULL !== $end_time)
			$search['create_time_less'   ] = (int) $end_time;

		if ($role === 'member')
			$search['utype']   = 'member'; 
		elseif ($role === 'merchant')
			$search['utype']   = 'merchant'; 
		elseif ($role === 'manage')
			$search['utype']   = 'manage'; 


		$result = self::search_engine()->search($search);
		$status = Kohana::config('user.status');
		$stats  = array();
		$data   = array();
		foreach ($status as $k => $v)
		{
			$stats[$v] = $k;
			$data [$k] = $type;
		}

		foreach ($result['list'] as $r)
		{
			$k = Arr::get($stats, $r['status']);
			unset($r['status']);
			$values   = array_values($r);
			$data[$k] = (int) $values[0];
		}

		return $data;
	}

	/*
	 * 事件处理器
	 */
	public static function event_handler ($event)
	{
		return User_Handler::instance($event);
	}

	private static function do_user_instance ($info)
	{
		$uid   = $info['uid'];
		$utype = $info['utype'];

		switch ($utype)
		{
		case 'manager' :
			return User_Manager::factory($uid, $info);

		case 'merchant' :
			return new User_Merchant($uid, $info);

		case 'member' :
		default: 
			return new User_Member($uid, $info);
		}
	}

	/*
	 * 用户搜索对象
	 */
	private static function search_engine ()
	{
		if (NULL === self::$_search)
			self::$_search = new User_Search();

		return self::$_search;
	}
        
        public static function  edit_info($info)
        {
            DB::update('user_basic')
                ->set (array('nickname' => $info['nickname'], 'realname' => $info['realname'], 'mobile' => $info['mobile'], 'comments' => $info['comments'] ))
                ->where('uid', '=', $info['uid'])
                ->execute();
        }
        
        public static function close_user($uid)
        {
            $uids = array($uid);
            $query = DB::select('uid')
                ->from('oct_data_config')
                ->where('parent', '=', $uid)
                ->execute();
            foreach ($query as $rs)
            {
                $uids[] = $rs['uid'];
            }
            $result = DB::update('user_basic')
                ->set (array('status' => $info['status'] ))
                ->where('uid', 'in', $uids)
                ->execute();
        }
        
        public static function get_today_num()
        {
            $begin = strtotime(date('Ymd', time()).'000000');
            $end   = strtotime(date('Ymd', time()).'235959');
            $count = DB::select(array('count("uid")', 'counts'))
            ->from('oct_data_config')
            ->where('ctime','>=',$begin)
            ->where('ctime','<=',$end)
            ->execute()
            ->get('counts');

            return $count + 1;
        }
}
